To maintain security over resources, users are given account names and passwords. Before the users can access the resources, the users must provide their account name and password to the system. The system then checks the provided account name and password, and confirms that they match before the user is granted access to the resources.
Of course, users are not perfect. Especially where passwords are keyed in using a keyboard, users sometimes make mistakes entering their passwords. This problem is exacerbated by the fact that passwords are typically not displayed on screen (to keep others from seeing them as they are entered), and by the requirement that the passwords become increasingly longer and complex (to keep others from guessing the password).
But while an occasional error entering the password is expected, repeated errors are not. At some point, the probability shifts from the user making a mistake entering his password to someone attempting to break into the account without authorization. To prevent unauthorized users from breaking into the resources using another's account, typically the hacked account is frozen until an administrator unlocks the account. If it turns out that the user simply made one too many mistakes entering his password, he is temporarily inconvenienced; but a hacker is kept out of the system.
While this design works well in some situations, problems can arise where identifiers have to be translated between different environments. For example, consider the situation where users are divided into different containers within a single server. Within a given container, user names are distinct (to avoid uncertainty about which user is intended), but user names can be duplicated across different containers. Assume that containers A and B each include a (different) user “Joe.” The name “Joe” is a flat name, and needs to be translated to the “Joe” of one of the containers. When “Joe” attempts to log in and access resources, the system has no way of knowing which user Joe is attempting to access the system. So the system attempts to authenticate “Joe” within each container in turn: for example, first with container A, then with container B. If the authentication within container A succeeds, then the user is granted access to the resources determined by container A. Otherwise, after the authentication within container A fails, the system attempts to authenticate “Joe” within container B. If the authentication within container B succeeds, then the user is granted access to the resources determined by container B. Otherwise, the user is informed that the authentication failed.
Note that in the above example, regardless of whether container A or container B successfully authenticates the user, the user is not informed of any other authentication attempts. For example, if the system cannot authenticate the user within container A, but the system can authenticate the user with container B, the user is not told that the user could not be authenticated within container A.
One way to address the problem described above is to have the user perform the translation. That is, “Joe” can be required to specify which container is to perform the authentication. But adding such a requirement would vary the login process from the norm (in that “Joe” would have to specify a container). In addition, “Joe” might not know to which container he belongs, and so could not specify the container. Finally, requiring users to identify their container limits the flexibility of the system: if a system administrator changes the containers without informing users, the users would be unable to log in to the containers.
In a related example, containers A and B can be on different servers, with the user logging into a proxy server. Other than the fact that servers A and B are both connected to the same proxy server, there might be no relationship between servers A and B. The proxy server is then responsible for determining which of servers A and B will be able to authenticate the user.
In ordinary usage, this straightforward approach to authentication works relatively well. But under unusual circumstances, the approach can have adverse consequences. For example, consider the situation above, and assume that “Joe” needs to be authenticated within container B several times in a row (e.g., “Joe” keeps losing his connection). Because the system tries to authenticate the user within container A first each time, the user Joe associated with container A might attempt to log into his account and be told that his account has been frozen, as it would appear to the system that someone attempted to break into the account of the user Joe associated with container A. A legitimate user has been inconvenienced in a situation where no inconvenience should have occurred.
Even ignoring the problem that a legitimate user can be inconvenienced when he should not be, this approach has other problems. It takes resources to attempt to authenticate “Joe” within container A, even when the authentication fails: resources that have to be allocated when “Joe” logs in, and released when the authentication fails. In addition, it takes the Joe authenticated within container B longer to log in than it does for the Joe authenticated within container A, because he first has to be rejected by container A every time.
The invention addresses these problems and others in the art.